# Copyright (c) 2008 Alvin Wang http://cloudwizard.com/
# License New BSD
# See README for additional information

"""
Amazon Web Services Cloud Support

"""

from cloudwizard.compute import ComputeService
from cloudwizard.compute import ComputeDevice
from boto.ec2.connection import EC2Connection
from cloudwizard.config import Config
from cloudwizard.ssh import Connection
import time


class Ec2(ComputeService):	# encapsulate connection
    """ComputeService API - EC2
    """

    def __init__(self, auth=None, username='default'):
        if auth:
            self.cloud_auth=auth
        else:
            self.cloud_auth = Config( cloud_abbrev = 'aws', config_name=username)
        self.cloud_obj = EC2Connection( self.cloud_auth.data['aws_access_id'], \
            self.cloud_auth.data['aws_secret_key'])

    def create(self, image_id=None, key_pair=None, 
            min_count=1, max_count=1, security_group=None, system_type=None):
        """Start an image_id - returns array of instances"""
        #'ami-b111f4d8' - ubuntu

        if image_id == None:
            print "Error"
            return
        try:
            images = self.cloud_obj.get_all_images(image_ids=[image_id])
        except:
            pass
        if key_pair == None:
            key_pair = self.cloud_auth.data['default_keypair']
        aws_reservation = images[0].run(min_count, max_count, key_pair)	    
        arr = []
        for instance in aws_reservation.instances:
            computer = Instance(auth=self.cloud_auth, cloud_device=instance)
            # username='default', instanceid=None,      cloud_device=None):
            arr.append(computer)
        return arr
        

    def delete(self, ip=None, dns=None, instance=None,instance_id=None, 
        reservation=None, **args):
        """stop a ec2 object or an array of them"""
        #'ami-b111f4d8'
        instances= self.olist()
        for instance in instances:
            if instance.id == instance:
                return self.cloud_obj.terminate_instances( \
                    instance_ids=[instance.id])

    def find(self, ip=None, dns=None, instance=None,instance_id=None, 
        reservation=None, **args):
        """find a ec2 object"""
        #'ami-b111f4d8'
        instance = Instance(auth=self.cloud_auth)
        if instance.active():
            return instance
        else:
            return None
                                
    def deleteall(self, ip=None, dns=None, instance=None,instance_id=None, 
        reservation=None):
        """stop all of them"""
        #More work to do on options
        instances= self.olist()
        ids=[]
        for instance in instances:
            ids.append(instance.id)
        return self.cloud_obj.terminate_instances(instance_ids=ids)

    def olist(self, status=None, reservation=None):
        """list all live ec2 instances as objects"""
        instances=[]
        reservations = self.cloud_obj.get_all_instances()
        for reservation in reservations:
            for instance in reservation.instances:
                instances.append(instance)
        return instances

    def plist(self, status=None,reservation=None):
        """print all live ec2 instances as objects"""
        instances= self.olist()
        for instance in instances:
            print instance.id,instance.state, \
                instance.public_dns_name, instance.key_name
        
    def status(self):
        instances = self.olist()
        for instance in instances:
            print instance.id, instance.state, instance.public_dns_name, \
                instance.key_nam

    #########################################################################

    def ec2_olist_amis(self, owner_id=None):
        return self.cloud_obj.get_all_images()

    def ec2_plist_amis(self, owner_id=None):
        amis = self.ec2_olist_amis( owner_id=None)
        for ami in amis:
            pass
    #########################################################################

    def ec2_create_keypair(self, key_name=None):
        """Create a keypair, you must supply a key_name.  
        files are stored in the default directory
        """
        kp = self.cloud_obj.create_key_pair(key_name)
        fileObj = open(self.cloud_auth.get_path()+'/aws.key.'+key_name,"w")
        fileObj.write(kp.material)
        fileObj.close

    def ec2_delete_keypair(self, key_name=None):
        self.cloud_obj.delete_key_pair(key_name)

    def ec2_olist_keypair(self):
        """Return all available keypair objects"""
        return self.cloud_obj.get_all_keypairs()

    def ec2_plist_keypair(self):
        """Print names of all available keypair objects"""
        kp = self.ec2_list_keypair()

    #########################################################################
    def ec2_olist_groups(self):     
        """list all security groups"""
        return self.cloud_obj.get_all_security_groups()

    def ec2_plist_groups(self):     
        """create more FW Functions"""
        return self.cloud_obj.get_all_security_groups()

    #########################################################################
    # reservation - list, stop
    
class Instance(ComputeDevice):	
    """ComputeDevice API - EC2"""
    def __init__(self, auth=None, username='default', instanceid=None,
            cloud_device=None):
        if auth:
            self.cloud_auth=auth
        else:
            self.cloud_auth = Config( cloud_abbrev = 'aws', config_name=username)
        self.cloud_obj = EC2Connection( self.cloud_auth.data['aws_access_id'], \
            self.cloud_auth.data['aws_secret_key'])
        
        if cloud_device:
            self.cloud_device = cloud_device
        
    def wait_state(self, state='running', timelimit=120):
        """Wait until"""
        i=0
        while i < timelimit:
            self.cloud_device.update()
            if self.cloud_device.state == state:

                return True
            time.sleep(1)
            i+=1
            print '.',
        print "Error: TIMEOUT waiting"
        return False
            
    def get_ssh(self):
        """Print names of all available keypair objects"""
        keypath = self.cloud_auth.aws_keypath(self.cloud_device.key_name)
        print 'instance=',self.cloud_device.id
        print 'dns=',self.cloud_device.public_dns_name
        print 'key=',keypath
        return Connection( self.cloud_device.public_dns_name, 
            private_key=keypath)
        
            # host, private_key = None,